package it.polito.let.http;


public class RequestBuilder {
	private Message message;

	public RequestBuilder(String messageStart) throws HTTPError {
		parseRequest(messageStart);
	}

	private void parseRequest(String messageStart) throws HTTPError {
		int delim, offset = 0;
		HTTPMethod method = null;
		String url, version;

		delim = messageStart.indexOf(" ");
		if(delim == -1)
			throw new HTTPError((short) 400,"Bad Request");
		try {
			method = HTTPMethod.valueOf(messageStart.substring(offset, delim).toUpperCase());
			checkRequestMethod(method);
		} catch(Exception e) {
			throw new HTTPError((short) 400,"Bad Request");
		}

		offset = delim + 1;

		delim = messageStart.indexOf(" ", offset);
		if(delim == -1)
			throw new  HTTPError((short) 400,"Bad Request");
		url = messageStart.substring(offset, delim);
		if(!url.startsWith("/"))
			throw new HTTPError((short) 400,"Bad Request");
		offset = delim + 1;

		version = messageStart.substring(offset).trim();
		checkVersion(version);

		message = new Request();
		((Request) message).setRequestMethod(method);
		((Request) message).setRequestURL(url);
		((Request) message).setHttpVersion(version);
	}

	private void checkVersion(String version) throws HTTPError {
		boolean isSupported = false;
		for(String supportedVersion : HTTPConstants.VERSIONS_SUPPORTED) {
			if(version.equals("HTTP/" + supportedVersion)) {
				isSupported = true;
				break;
			}
		}
		if(!isSupported) throw new HTTPError((short) 505, "HTTP Version Not Supported");
	}

	private void checkRequestMethod(HTTPMethod method) throws HTTPError {
		boolean isSupported = false;
		for(HTTPMethod supportedRequest : HTTPConstants.REQUESTS_SUPPORTED) {
			if(method.equals(supportedRequest)) {
				isSupported = true;
				break;
			}
		}
		if(!isSupported) throw new HTTPError((short) 501, "Not Implemented");
	}

	public void parseHeaderLine(String header) throws HTTPError {
		int delim;
		String fieldName, fieldValue;
		Header headerValue;

		delim = header.indexOf(':');
		if(delim == -1) throw new HTTPError((short) 400,"Bad Request");
		fieldName = header.substring(0, delim).trim();
		fieldValue = header.substring(delim + 1).trim();
		headerValue = (isParameterField(fieldName)) ? Header.parseHeader(fieldValue) : new Header(fieldValue);
		message.setHeaderField(fieldName, headerValue);
	}


	private boolean isParameterField(String fieldName) {
		for(int i = 0; i < HTTPConstants.PARAMETER_HEADERS.length; i++) {
			if(HTTPConstants.PARAMETER_HEADERS[i].equals(fieldName)) return true;
		}
		return false;
	}

	public Message getMessage() {
		return message;
	}
}
